package aControllerLayer;

import java.util.ArrayList;
import java.util.Random;

import aModelLayer.Battle;
import aModelLayer.BattleCharacter;
import aModelLayer.BattleEnemy;
import aModelLayer.Game;
import aModelLayer.Menu;
import aViewLayer.BattleView;
import aViewLayer.View;
import aaGame.GameEngine;
import azServiceLayer.AudioPlayer;
import azServiceLayer.Input;
import azServiceLayer.R;

public class BattleController extends Controller {
	private Game mModel;
	private GameEngine mEngine;
	private BattleView view;
	private int mKey = -100;
	
	BattleCharacter[] battleCharacters;
	BattleEnemy[] battleEnemies;
	
	Battle battle;
	Menu battleMenu;
	Menu targetSelectMenu;
	
	Menu currentMenu;
	
	public boolean menuAccess;
	public boolean targetSelectAccess;
	
	ArrayList<Integer> availableAction = new ArrayList<Integer>();
	private AudioPlayer player;
	
	public BattleController(Game model, GameEngine engine){

		player = new AudioPlayer(this.getClass().getResource(R.music.battle), AudioPlayer.MIDI);
		mModel = model;
		mEngine = engine;
		
		battleMenu = new Menu(new String[]{"Attack", "Magic", "Item", "Defend", "Run"});
		
		currentMenu = battleMenu;
		
		battleCharacters = model.getBattleCharacters();
	}

	@Override
	public View getView() {
		// TODO Auto-generated method stub
		return view;
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		for (int i = 0; i < battleCharacters.length; i++) {
			if (battleCharacters[i].getCurrentActionBar() < BattleCharacter.actionBarMax) { 
				battleCharacters[i].incrementActionBar();
			} else if (!availableAction.contains(i)){				
				availableAction.add(i);
			}
		}
		
		for (int i = 0; i < battleEnemies.length; i++) {
			if (battleEnemies[i].getCurrentActionBar() < BattleEnemy.actionBarMax) { 
				battleEnemies[i].incrementActionBar();
			} else {
				Random generator = new Random();
				battle.enemyAttack(i, generator.nextInt(battleCharacters.length));
				battleEnemies[i].resetActionBar();
			}
		}
		
		if (availableAction.size() > 0 && !targetSelectAccess) {
			menuAccess = true;
			view.setMenuAccess(true); 
		}
	}

	@Override
	public void keyPressed(int key) {
		// TODO Auto-generated method stub
		if (targetSelectAccess) {
			switch(key){		
			case Input.DOWN: 
				currentMenu.nextOption();
				break;
			case Input.UP:
				currentMenu.previousOption();
				break;
			case Input.Z:
				
				battle.characterAttack(availableAction.get(0), Integer.parseInt(currentMenu.getCurrentOption()));					
				battleCharacters[availableAction.get(0)].resetActionBar();
				availableAction.remove(0);
				
				currentMenu = battleMenu;
				
				targetSelectAccess = false;	
				view.setTargetSelectAccess(false);
				
				if (availableAction.isEmpty()) {
					menuAccess = false;
					view.setMenuAccess(false);
				}
				
				checkEndBattle();
				break;
			case Input.ESCAPE:
				mEngine.currentController = mEngine.mRoomController;
				mEngine.printControllerName();
				break;
			}
		}
		
		if (menuAccess) {
			switch(key){		
			case Input.DOWN: 
				currentMenu.nextOption();
				break;
			case Input.UP:
				currentMenu.previousOption();
				break;
			case Input.Z:
				switch(currentMenu.getCurrentOption()){
				case "Attack":
					
					ArrayList<String> availableTargets = new ArrayList<String>();
					for (int i = 0; i < battleEnemies.length; i++)
						if (!battleEnemies[i].isDead())
							availableTargets.add(Integer.toString(i));
										
					targetSelectMenu = new Menu(availableTargets);
					currentMenu = targetSelectMenu;
					
					view.setTargetSelectAccess(true);
					view.setMenuAccess(false);
					targetSelectAccess = true;
					menuAccess = false;
					
					break;
				case "Magic":
					;
					break;
				case "Item":
					;
					break;
				case "Defend":
					;
					break;
				case "Run":
					Random generator = new Random();
					if (generator.nextInt(10) != 0) {
						endBattle();
						mEngine.printControllerName();
					}
					break;
				}
				currentMenu.select();
				break;
			case Input.ESCAPE:
				endBattle();
				mEngine.printControllerName();
				break;
			}
		}	
	}

	@Override
	public void keyReleased(int key) {
		// TODO Auto-generated method stub
		if (key == mKey)
			mKey = -100;
	}
	
	public void startNewBattle() {
		battle = new Battle(mModel);
		player = new AudioPlayer(this.getClass().getResource(R.music.battle), AudioPlayer.MIDI);
		battleEnemies = battle.getBattleEnemies();
		view = new BattleView(mModel, this);
		view.startNewBattle(battle, battleEnemies);
	}
	
	public void checkEndBattle() {
		if (battle.battleWon()) {
			endBattle();
		} else if (battle.battleLost()) {
			mEngine.currentController = mEngine.mTittleMenuController;
		}
	}
	
	public void endBattle() {
		menuAccess = false;
		targetSelectAccess = false;
		availableAction.clear();
		
		for (int i = 0; i < battleCharacters.length; i++) {
			battleCharacters[i].resetActionBar();
		}
		player.stopMusic();
		mEngine.currentController = mEngine.mRoomController;
		mEngine.currentController.playMusic();
	}
	
	public boolean menuAccess() {
		return menuAccess;
	}
	
	public Menu getBattleMenu() {
		return battleMenu;
	}
	
	public Menu getTargetSelectMenu() {
		return targetSelectMenu;
	}
	
	public ArrayList<Integer> getAvailableAction() {
		return availableAction;
	}

	@Override
	public void playMusic() {
		// TODO Auto-generated method stub
		player.playMusic();
	}

}
